package org.tuestudent.grouppa;

import java.util.ArrayList;
import java.util.Date;

import org.tuestudent.grouppa.ChatViewController.GetAllMessagesResponse;
import org.tuestudent.grouppa.ChatViewController.GetNewMessagesResponse;
import org.tuestudent.grouppa.ChatViewController.PostNewMessageResponse;

import android.app.AlertDialog;
import android.app.Fragment;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class Chat extends Fragment {
    
    //declaration and initialization of variables
    ChatViewController CC = ChatViewController.getInstance();
    ArrayList<ChatMessage> chatList = new ArrayList<ChatMessage>();
    ArrayList<ChatMessage> unreadMessages = new ArrayList<ChatMessage>();
    ProgressDialog currentProgressDialog = null;
    AlertDialog currentAlertDialog = null;
    String time;
    String lastDate = "";
    String messageDate;
    String name = Main.getContext().currentUserName;
    private GrouppaScreen grouppaScreen;
    private ListView lv;
    private CustomListViewAdapter listAdapter;
    private ArrayList<String> months = new ArrayList<String>();
    private static Chat instance;

    public static Chat getInstance() {
        return instance;
    }

    /**
     * send the text message to the chat server
     * 
     * @param myText
     *            the text message of the user
     */
    public void sendText() {
        createMessage();
    }
    
    /**
     * gets the message from the edit text view
     * 
     * @param chatMessage
     */
    private void createMessage() {
        //get the content of the edit text
        String myText =
                ((EditText) getActivity().findViewById(R.id.typeBox)).getText()
                        .toString();
        //empty the edit text field (for next message)
        ((EditText) getActivity().findViewById(R.id.typeBox)).setText("");
        //check if the message is not empty or only consisting of spaces/empty lines
        if ( !myText.trim().isEmpty()) {
            //create a new chat message
            ChatMessage message = new ChatMessage();
            //add text of the chat message
            message.text = myText;
            //add the time stamp to the message
            Date now = new Date();
            message.date = now;
            //add the author to the message
            message.author = name;
            //send the message to the server
            CC.postNewMessage(message);
        }
    }
    
    @SuppressWarnings("deprecation")
    private void displayMessages() {
        //while there a messages that are not displayed yet
        while ( !unreadMessages.isEmpty()) {
            //take a message of the non displayed messages (chronologic order)
            ChatMessage message = unreadMessages.remove(0);
            Date messageTime = message.date;
            messageDate=messageTime.getDate() + " " + months.get(messageTime.getMonth()) + " " + (messageTime.getYear()+1900);
            //if the date of the message is of the same day as previous message
            if(lastDate.equals(messageDate)){
                
            } else {
                //generate a timestamp stating the day
                lastDate = messageDate;
                ChatMessage mes = new ChatMessage();
                mes.author = "date";
                mes.text = lastDate;
                chatList.add(mes);
            }
            //add the message to the listview
            chatList.add(message);
        }
        //notify the adapter that the dataset has changed
        listAdapter.notifyDataSetChanged();
        //set the focus on the final item
        lv.setSelection(lv.getAdapter().getCount()-1);
    }
    
    
    //methods that adds the months to the months array, this is for the timestamp
    private void generateMonths(){
        months.add("January");
        months.add("February");
        months.add("March");
        months.add("April");
        months.add("May");
        months.add("Jun");
        months.add("July");
        months.add("August");
        months.add("September");
        months.add("October");
        months.add("November");
        months.add("December");
    }

    // ----------------onCreateView for the Chat Fragment-------------------
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        // Inflate the view to its container
        View chat = inflater.inflate(R.layout.fragment_chat, container, false);
        //find the button
        Button send = (Button) chat.findViewById(R.id.send_chat_message);
        //add an onclicklistener to the button
        send.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {
                //send the text message when the button is clicked
                sendText();
            }
        });
        
        // make enter-key also send the message (only works for physical keyboards)
        EditText chatBox = ((EditText) chat.findViewById(R.id.typeBox));
        chatBox.setOnKeyListener(new OnKeyListener() {
            public boolean onEditorAction(View view, int press, KeyEvent event) {
              
            if ( (event.getAction() == KeyEvent.ACTION_DOWN ) &&
                    ((press == KeyEvent.KEYCODE_ENTER)||
                            press == KeyEvent.KEYCODE_DPAD_CENTER )) { 
                sendText();
                return true;
            }
                return false;
            }

            @Override
            public boolean onKey(View v, int press, KeyEvent event) {
                if ( (event.getAction() == KeyEvent.ACTION_DOWN ) &&
                        ((press == KeyEvent.KEYCODE_ENTER)||
                                press == KeyEvent.KEYCODE_DPAD_CENTER ) ){ 
                    sendText();
                            
                }
                return false;
            }
        });
        
        //make sure there is nothing shown yet
        chatList.clear();
        //get the listview
        lv = (ListView) chat.findViewById(R.id.chatList);
        //create a new adapter
        listAdapter =
                new CustomListViewAdapter(getActivity(),R.layout.row, chatList);
        //add the adapter to the listview
        lv.setAdapter(listAdapter);
        generateMonths();
        return chat;

    };

    // Method executed when the fragment is started
    @Override
    public void onStart() {
        super.onStart();
        instance = this;
        AppContext ctx = Main.getContext();
        ctx.currentGrouppaFragment = this;
        ctx.setCurrentViewController(CC);
        CC.getAllMessages();

        //clearing chat notifications
        NotificationManager mNotificationManager =
            (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.cancel(ViewController.notificationIds.chatMessageNotification.ordinal());
    }

    // Method executed when the server receives a new message is posted by a user
    public void onNewMessages(GetNewMessagesResponse response) {
        //if it is a successful retrieval of the message
        if (response.retrieved) {
            //get all new messages
            for (int i = 0; i < response.allMessages.length; i++ ) {
                unreadMessages.add(response.allMessages[i]);
            }
            // if there were new messages received by the server
            if(!unreadMessages.isEmpty()){
                //display the messages
                displayMessages();
            }
        } else { 
            // if the messages could not be retrieved, display the reason
            grouppaScreen.errorPopup(response.errorReason);
        }
    }

    // Method executed when a user posts a new message successfully to the server
    public void onPostNewMessageResponse(PostNewMessageResponse response) {
        //if the post was successful
        if (response.posted) {
            //if the messages are not displayed yet
            if(response.allMessages != null) {   
                for (int i = 0; i < response.allMessages.length; i++ ) {
                    unreadMessages.add(response.allMessages[i]);
                }
                // if there are no unread messages
                if(!unreadMessages.isEmpty()){
                    displayMessages();
                }
            }
        } else { 
            //if the message could not be sent to the server, state why
            grouppaScreen.errorPopup(response.errorReason);
        }
    }

    public void onGetAllMessagesResponse(GetAllMessagesResponse response) {
        //when getting a respond when trying to retrieve all messages from the server
        if (response.retrieved) {
            //clear all current displayed messages
            chatList.clear();
            //notify the adapter
            listAdapter.notifyDataSetChanged();
            //clear the list of not displayed messages
            unreadMessages.clear();
            //add all messages to the not displayed messages
            for (int i = 0; i < response.allMessages.length; i++ ) {
                unreadMessages.add(response.allMessages[i]);
            }
            //if there are messages to display, display them
            if(!unreadMessages.isEmpty()){
                displayMessages();
            }
        } else {
            //if there was an error, show why
            grouppaScreen.errorPopup(response.errorReason);
        }
    }
}
